package com.lamb.script.core.executor.loader;


import com.lamb.script.core.utils.ScriptConsole;
import com.lamb.script.core.utils.HttpUtil;
import com.lamb.script.core.utils.ScriptUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * maven jar包依赖.
 *
 * @author : lamb
 * @version : 1.0
 * @date :  2019-08-08 9:21
 **/
public class MavenJarLoader {

    private static final String JAR_MAVEN_PATH = "/%1$s/%2$s/%4$s/%2$s-%4$s.jar";
    private static final String METADATA_MAVEN_PATH = "/%1$s/%2$s/%4$s/maven-metadata.xml";
    private static final String SPLIT_FILE_PATH = "/";
    private static final String SPLIT_SPOT = ".";
    private static final String SNAPSHOT = "SNAPSHOT";

    /**
     * 本地文件.
     */
    private final String localRepository;

    /**
     * 仓库服务器地址.
     */
    private final String mirrorUrl;

    /**
     * 脚本输出器.
     */
    private final ScriptConsole scriptConsole;

    public MavenJarLoader(String localRepository, String mirrorUrl, ScriptConsole scriptConsole) {
        this.localRepository = localRepository;
        this.mirrorUrl = mirrorUrl;
        this.scriptConsole = scriptConsole;
    }

    /**
     * 查找jar包.
     *
     * @param jarFile jar文件配置.
     */
    public File findJar(String jarFile) throws IOException {
        String[] ss = jarFile.split(":");
        ss[0] = ss[0].replace(SPLIT_SPOT, SPLIT_FILE_PATH);
        String path = String.format(JAR_MAVEN_PATH, (Object[]) ss);
        File file = new File(localRepository + path.substring(path.lastIndexOf(SPLIT_FILE_PATH)));
        if (!file.exists()) {
            String metadataXml = String.format(METADATA_MAVEN_PATH, (Object[]) ss);
            if (metadataXml.contains(SNAPSHOT)) {
                byte[] bytes = HttpUtil.httpGet(mirrorUrl + metadataXml);
                String xml = ScriptUtil.toString(bytes);
                List<String> matcherResult = getMatcherResult(xml, "<value>([0-9\\-\\.]+)</value>");
                if (matcherResult.isEmpty()) {
                    matcherResult = getMatcherResult(xml, "<buildNumber>([0-9\\-\\.]+)</buildNumber>");
                    if (matcherResult.isEmpty()) {
                        scriptConsole.error("snapshot not found value, on xml = " + xml);
                        return file;
                    }
                    String buildNumber = matcherResult.get(0);
                    matcherResult = getMatcherResult(xml, "<timestamp>([0-9\\-\\.]+)</timestamp>");
                    String version = ss[3].substring(0, ss[3].length() - 8) + matcherResult.get(0) + buildNumber;
                    path = path.substring(0, path.lastIndexOf("/") + 1)
                            + ss[1] + "-" + version + ".jar";
                } else {
                    path = path.substring(0, path.lastIndexOf("/") + 1)
                            + ss[1] + "-" + matcherResult.get(0) + ".jar";
                }
            }
            String urlString = mirrorUrl + path;
            scriptConsole.info("findJar on url = " + urlString);
            byte[] bytes = HttpUtil.httpGet(urlString);
            boolean saveStatus = ScriptUtil.writeFile(file.getAbsolutePath(), bytes, scriptConsole);
            scriptConsole.info("findJar download " + file.getAbsolutePath() + " " +
                    (saveStatus ? "success" : "failed") + ", file size = " + bytes.length);
        }
        return file;
    }

    /**
     * 正则提取返回结果
     *
     * @param content 查找的文本内容
     * @param regex   正则表达式
     */
    public List<String> getMatcherResult(String content, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        List<String> result = new ArrayList<>();

        while (matcher.find()) {
            result.add(matcher.group(1));
        }
        return result;
    }
}
